﻿using BEPUphysics;
using BEPUphysics.Entities;
using Microsoft.Xna.Framework;

namespace Asplode.Physics
{

    public class PhysicsEventHandler
    {
        private Space Space;

        public PhysicsEventHandler(Space space)
        {
            Space = space;
        }

        public void subscribe(EventDispatcher EventDispatcher)
        {
            EventDispatcher.BoxSpawn += new EventDispatcher.BoxSpawnHandler(EventDispatcher_BoxSpawn);
            EventDispatcher.BoxShot += new EventDispatcher.BoxShotHandler(EventDispatcher_BoxShot);
            EventDispatcher.Explosion += new EventDispatcher.ExplosionHandler(EventDispatcher_Explosion);
            EventDispatcher.HumanSpawn += new EventDispatcher.HumanSpawnHandler(EventDispatcher_HumanSpawn);
            EventDispatcher.MortarShot += new EventDispatcher.MortarShotHandler(EventDispatcher_MortarShell);
            EventDispatcher.RemoveEntity += new EventDispatcher.RemoveEntityHandler(EventDispatcher_RemoveEntity);
            EventDispatcher.ZombieSpawn += new EventDispatcher.ZombieSpawnHandler(EventDispatcher_ZombieSpawn);
            
        }

        void EventDispatcher_BoxShot(Entity Box, Vector3 initialForce)
        {
            Space.add(Box);
            Box.applyImpulse(Box.centerOfMass,initialForce);
        }        

        void EventDispatcher_BoxSpawn(Box box, Vector3 initialForce)
        {
            Space.add(box);
            box.applyImpulse(box.centerOfMass, initialForce);
        }

        void EventDispatcher_Explosion(Vector3 position, float magnitude, float maxDistance)
        {
            BEPUphysics.Explosion explosion = new Explosion(position, magnitude, maxDistance, Space, ExplosionFalloffType.Linear);
            explosion.explode();
        }

        void EventDispatcher_HumanSpawn(Entity entity)
        {
            // TODO: Set localInertiaTensorInverse to keep the entity from rotating about the X and Z axes.
            Space.add(entity);
        }

        void EventDispatcher_MortarShell(Entity entity, Vector3 initialAcceleration)
        {
            Space.add(entity);

            // f = ma
            Vector3 initialForce = entity.mass * initialAcceleration;
            entity.linearVelocity = initialAcceleration;
            //entity.applyImpulse(entity.centerOfMass, initialForce);
        }

        void EventDispatcher_RemoveEntity(Entity entity)
        {
            if (Space.entities.Contains(entity))
            {
                Space.remove(entity);
            }
        }

        void EventDispatcher_ZombieSpawn(Entity entity)
        {
            // TODO: Set localInertiaTensorInverse to keep the entity from rotating about the X and Z axes.
            Space.add(entity);
        }
    }
}
